
/**
 * https://yuque.antfin-inc.com/vision/buzhou/soykun
 * 拖拽与节点相邻的线段时，获取节点与线的交点，对于交点不存在的情形，添加新的控制点
 * bbox是节点的边界
 * shape是形状
 * point是线的中点
 * vertical，线是垂直还是水平
 * @param {object} param0 获取相交点的位置
 * @return {object} added, joint
 */
export function getJoinPoint({ bbox, shape = 'ROUNDED_RECT', point, vertical }) {
  vertical = !!vertical;
  const cood = {
    true: 'x',
    false: 'y'
  };
  const min = {
    true: 'minX',
    false: 'minY'
  };
  const max = {
    true: 'maxX',
    false: 'maxY'
  };
  switch (shape) {
    case 'ROUNDED_RECT': // 圆角矩形
      if (point[cood[vertical]] >= bbox[min[vertical]] + 4 && point[cood[vertical]] <= bbox[max[vertical]] - 4) {
        // 交点在横线上
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ? bbox.maxX : bbox.minX),
            y: vertical ? (point.y > bbox.centerY ? bbox.maxY : bbox.minY) : point.y
          }
        };
      } else if (point[cood[vertical]] >= bbox[min[vertical]] && point[cood[vertical]] < bbox[min[vertical]] + 4) {
        // 交点在左边/上边的圆角上
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ?
              bbox.maxX - 4 + Math.sqrt(16 - Math.pow(bbox.minY + 4 - point.y, 2)) :
              bbox.minX + 4 - Math.sqrt(16 - Math.pow(bbox.minY + 4 - point.y, 2))
            ),
            y: vertical ? (point.y > bbox.centerY ?
              bbox.maxY - 4 + Math.sqrt(16 - Math.pow(bbox.minX + 4 - point.x, 2)) :
              bbox.minY + 4 - Math.sqrt(16 - Math.pow(bbox.minX + 4 - point.x, 2))) :
              point.y
          }
        };
      } else if (point[cood[vertical]] >= bbox[max[vertical]] - 4 && point[cood[vertical]] <= bbox[max[vertical]]) {
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ?
              bbox.maxX - 4 + Math.sqrt(16 - Math.pow(point.y - bbox.maxY + 4, 2)) :
              bbox.minX + 4 - Math.sqrt(16 - Math.pow(point.y - bbox.maxY + 4, 2))
            ),
            y: vertical ? (point.y > bbox.centerY ?
              bbox.maxY - 4 + Math.sqrt(16 - Math.pow(point.x - bbox.maxX + 4, 2)) :
              bbox.minY + 4 - Math.sqrt(16 - Math.pow(point.x - bbox.maxX + 4, 2))) :
              point.y
          }
        };
      }
      break;
    case 'CIRCLE':
      if (point[cood[vertical]] >= bbox[min[vertical]] && point[cood[vertical]] <= bbox[max[vertical]]) {
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ?
              bbox.centerX + Math.sqrt(16 - Math.pow(bbox.centerY - point.y)) :
              bbox.centerX - Math.sqrt(16 - Math.pow(bbox.centerY - point.y))),
            y: vertical ? (point.y > bbox.centerY ?
              bbox.centerY + Math.sqrt(16 - Math.pow(bbox.centerX - point.x)) :
              bbox.centerY - Math.sqrt(16 - Math.pow(bbox.centerX - point.x))) : point.y
          }
        };
      }
      break;
    case 'RHOMEBUS':
      if (point[cood[vertical]] >= bbox[min[vertical]] && point[cood[vertical]] <= bbox[max[vertical]]) {
        // 分八种情况讨论
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ?
              (point.y < bbox.centerY ? ((point.y - bbox.minY) * (bbox.maxX - bbox.centerX) / (bbox.centerY - bbox.minY) + bbox.centerX) :
                ((bbox.maxY - point.y) * (bbox.maxX - bbox.centerX) / (bbox.maxY - bbox.centerY) + bbox.centerX)
              ) :
              (point.y < bbox.centerY ? (bbox.centerX - (point.y - bbox.minY) * (bbox.centerX - bbox.minX) / (bbox.centerY - bbox.minY)) :
                (bbox.centerX - (bbox.maxY - point.y) * (bbox.centerX - bbox.minX) / (bbox.maxY - bbox.centerY))
              )
              ),
            y: vertical ? (point.y > bbox.centerY ?
              (point.x < bbox.centerX ? ((point.x - bbox.minX) * (bbox.maxY - bbox.centerY) / (bbox.centerX - bbox.minX) + bbox.centerY) :
                ((bbox.maxX - point.x) * (bbox.maxY - bbox.centerY) / (bbox.maxX - bbox.centerX) + bbox.centerY)
              ) :
              (point.x < bbox.centerX ? (bbox.centerY - (point.x - bbox.minX) * (bbox.centerY - bbox.minY) / (bbox.centerX - bbox.minX)) :
                (bbox.centerY - (bbox.maxX - point.x) * (bbox.centerY - bbox.minY) / (bbox.maxX - bbox.centerX))
              )) : point.y
          }
        };
      }
      break;
    case 'RECT':
    default:
      if (point[cood[vertical]] >= bbox[min[vertical]] && point[cood[vertical]] <= bbox[max[vertical]]) {
        // 分四种情况讨论
        return {
          added: undefined,
          joint: {
            x: vertical ? point.x : (point.x > bbox.centerX ? bbox.maxX : bbox.minX),
            y: vertical ? (point.y > bbox.centerY ? bbox.maxY : bbox.minY) : point.y
          }
        };
      }
      break;
  }

  // 交点在节点外侧
  if (vertical) {
    if (point.x < bbox.centerX) {
      return {
        added: {
          x: point.x,
          y: bbox.centerY
        },
        joint: {
          x: bbox.minX,
          y: bbox.centerY
        }
      };
    }
    return {
      added: {
        x: point.x,
        y: bbox.centerY
      },
      joint: {
        x: bbox.maxX,
        y: bbox.centerY
      }
    };
  }
  if (point.y < bbox.centerY) {
    return {
      added: {
        x: bbox.centerX,
        y: point.y
      },
      joint: {
        x: bbox.centerX,
        y: bbox.minY
      }
    };
  }
  return {
    added: {
      x: bbox.centerX,
      y: point.y
    },
    joint: {
      x: bbox.centerX,
      y: bbox.maxY
    }
  };
}
